﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Billing.WindowsBase;
using Infragistics.Win.UltraWinTree;
using System.Globalization;
using Billing.DataObjects;
using System.Data.Linq;
using System.Linq;

namespace Billing.Windows.Shell
{
    public partial class DataRightsForm : FormBase
    {
        private ShellDataContext mShellDataContext = new ShellDataContext();
        UltraTreeNode mDRUltraTreeNode = null;
        UltraTreeNode mActiveParentNode;
        private Dictionary<Guid, UltraTreeNode> AddNodesList = new Dictionary<Guid, UltraTreeNode>();
        private Dictionary<Guid, UltraTreeNode> RemoveNodesList = new Dictionary<Guid, UltraTreeNode>();

        private UltraTreeNode DRUltraTreeNode
        {
            get
            {
                if (mDRUltraTreeNode == null)
                    mDRUltraTreeNode = new UltraTreeNode();
                return mDRUltraTreeNode;
            }
        }

        public DataRightsForm()
            : base(true)
        {
            InitializeComponent();
        }

        public DataRightsForm(string x)
            : base(true)
        {
            InitializeComponent();
        }

        #region LoadDataTrees

        private int i = 0;

        private void LoadParentDataTree()
        {
            this.trParentData.Nodes.Clear();
            this.trChildData.Nodes.Clear();

            UltraTreeNode rootNodes;
            UltraTreeNode rootsChildrenNodes;

            System.Data.Linq.ISingleResult<GetRootsResult> roots = mShellDataContext.GetRoots();

            foreach (GetRootsResult item in roots)
            {
                i++;
                rootNodes = new UltraTreeNode(i.ToString(), item.NAME);
                TagInfo childrenTag = new TagInfo(item.GUID, item.GUID);
                rootNodes.Tag = childrenTag;
                foreach (INodeObject childItem in mShellDataContext.GetRightChilds(item.NAME, Convert.ToString(item.GUID)))
                {
                    i++;
                    rootsChildrenNodes = new UltraTreeNode(i.ToString(), childItem.Name);
                    childrenTag = new TagInfo((Guid)childItem.ChildGUID, item.GUID);
                    rootsChildrenNodes.Tag = childrenTag;
                    rootNodes.Nodes.Add(rootsChildrenNodes);
                }
                this.trParentData.Nodes.Add(rootNodes);
            }
            trParentData.ExpandAll();
        }

        private void LoadChildDataTree()
        {
            Cursor = Cursors.WaitCursor;
            this.trChildData.Nodes.Clear();
            mActiveParentNode = this.trParentData.ActiveNode;
            AddNode(null, new UltraTreeNode());
            Cursor = Cursors.Default;
        }
        #endregion

        private void ubUpdate_Click(object sender, System.EventArgs e)
        {
            foreach (UltraTreeNode ultraTreeNode in AddNodesList.Values)
            {
                TagInfo tf = (TagInfo)(ultraTreeNode.Tag);

                mShellDataContext.SaveCheckState(tf.CGUID,
                                                         tf.CtGUID,
                                                         tf.PGUID,
                                                         tf.PtGUID,
                                                         true);
            }

            foreach (UltraTreeNode ultraTreeNode in RemoveNodesList.Values)
            {
                TagInfo tf = (TagInfo)(ultraTreeNode.Tag);
                mShellDataContext.SaveCheckState(tf.CGUID,
                                                         tf.CtGUID,
                                                         tf.PGUID,
                                                         tf.PtGUID,
                                                         false);
            }
            AddNodesList.Clear();
            RemoveNodesList.Clear();
        }

        private void frmDataRights_Load(object sender, System.EventArgs e)
        {
            LoadParentDataTree();
        }

        private void trParentData_AfterSelect(object sender, Infragistics.Win.UltraWinTree.SelectEventArgs e)
        {
            if (AddNodesList.Count != 0 || RemoveNodesList.Count != 0)
            {
                if (MessageBox.Show("შევინახო ცვლილებები?", "", MessageBoxButtons.YesNo) == DialogResult.Yes)
                    ubUpdate_Click(this, new EventArgs());
                else
                {
                    AddNodesList.Clear();
                    RemoveNodesList.Clear();
                }
            }
            LoadChildDataTree();
        }

        private void trChildData_AfterCheck(object sender, Infragistics.Win.UltraWinTree.NodeEventArgs e)
        { //((DataValueBase)e.TreeNode.Tag).Updated = true; 
        }

        private void trChildData_BeforeCheck(object sender, Infragistics.Win.UltraWinTree.BeforeCheckEventArgs e)
        {
            if (this.trParentData.ActiveNode.IsRootLevelNode && (e.TreeNode.CheckedState != System.Windows.Forms.CheckState.Checked))
                e.Cancel = true;
            if (!this.trParentData.ActiveNode.IsRootLevelNode)
            {
                TagInfo tag = (TagInfo)(e.TreeNode.Tag);
                if (e.TreeNode.CheckedState == System.Windows.Forms.CheckState.Checked)
                {
                    if (AddNodesList.ContainsKey(tag.CGUID))
                        AddNodesList.Remove(tag.CGUID);
                    else
                        if (RemoveNodesList.ContainsKey(tag.CGUID) == false)
                            RemoveNodesList.Add(tag.CGUID, e.TreeNode);
                }
                else
                {
                    if (RemoveNodesList.ContainsKey(tag.CGUID))
                        RemoveNodesList.Remove(tag.CGUID);
                    else
                        if (AddNodesList.ContainsKey(tag.CGUID) == false)
                            AddNodesList.Add(tag.CGUID, e.TreeNode);
                }
            }
        }

        private void ubRefresh_Click(object sender, System.EventArgs e)
        {
            this.LoadParentDataTree();
        }

        //private DataRow[] GetNextNodes(DataRow row, IEnumerator<GetTreeResult> tree)
        //{
        //    if (dataTable.Columns.Count == 0)
        //    {
        //        return new DataRow[0];
        //    }
        //    string filterexpression = String.Format("pGUID = '{0}'", row != null ? row[3] : ((TagInfo)(utn.Tag)).CtGUID);
        //    return dataTable.Select(filterexpression);
        //}

        private UltraTreeNode GenarateTree(UltraTreeNode ultraTreeNode, params bool[] list)
        {
            if (list.Length == 0)
            {
                TagInfo tag = (TagInfo)(ultraTreeNode.Tag);
                UltraTreeNode uTreeNode;
                UltraTreeNode ulTNode;
                foreach (GetChildrenResult child in mShellDataContext.GetChildren((Guid?)tag.CtGUID))
                {
                    i++;
                    uTreeNode = new UltraTreeNode(i.ToString(), child.NAME);
                    uTreeNode.Tag = new TagInfo(child.ChGUID, child.drctGUID, tag.PGUID, tag.PtGUID);
                    foreach (GetCheckedListResult item in mShellDataContext.GetCheckedList((Guid?)tag.CGUID, (Guid?)tag.PGUID, (Guid?)((TagInfo)uTreeNode.Tag).CGUID))
                    {
                        i++;
                        ulTNode = new UltraTreeNode(i.ToString(), item.NAME);
                        ulTNode.Tag = new TagInfo(item.GUID, ((TagInfo)(uTreeNode.Tag)).CGUID, tag.PGUID, tag.PtGUID);
                        ulTNode = GenarateTree(ulTNode);
                        if (item.Type == 1)
                        {
                            ulTNode.CheckedState = System.Windows.Forms.CheckState.Checked;
                        }
                        uTreeNode.Nodes.Add(ulTNode);
                    }
                    ultraTreeNode.Nodes.Add(uTreeNode);
                }
            }
            return ultraTreeNode;
            //return new UltraTreeNode();
        }
        private void AddNode(INodeObject tree, UltraTreeNode ownerUltraTreeNode)
        {
            List<INodeObject> treeResults = null;
            Guid dataTypesGuid = new Guid("12D276E7-44B6-461B-9644-6D534794BA04");
            Guid usersGuid = new Guid("11ff3905-3f07-4277-ada2-79979f55d634");

            if (tree != null)
            {
                i++;
                if (tree.GetType() == typeof(GetTreeResult))
                {
                    UltraTreeNode uTreeNode = new UltraTreeNode(i.ToString(), tree.Name);
                    TagInfo obj = new TagInfo((Guid)tree.ChildGUID, (Guid)tree.ChildTypeGUID, (Guid)tree.ParentGUID, (Guid)tree.ParentTypeGUID);
                    uTreeNode.Tag = obj;
                    ownerUltraTreeNode = ownerUltraTreeNode.Nodes[ownerUltraTreeNode.Nodes.Add(uTreeNode)];
                    ownerUltraTreeNode.Override.NodeStyle = NodeStyle.CheckBox;

                    treeResults = mShellDataContext.GetRightChilds(tree.Name, ((TagInfo)(mActiveParentNode.Tag)).CGUID.ToString()).Cast<INodeObject>().ToList<INodeObject>();
                    foreach (INodeObject item in treeResults)
                    {
                        i++;
                        uTreeNode = new UltraTreeNode(i.ToString(), item.Name);
                        obj = new TagInfo((Guid)item.ChildGUID, (Guid)tree.ChildGUID, (Guid)((TagInfo)(mActiveParentNode.Tag)).CGUID, (Guid)tree.ParentGUID);
                        uTreeNode.Tag = obj;
                        if (item.Type == 1)
                            uTreeNode.CheckedState = System.Windows.Forms.CheckState.Checked;
                        if (obj.PtGUID != dataTypesGuid)
                        {
                            uTreeNode = GenarateTree(uTreeNode);
                            ownerUltraTreeNode.Nodes.Add(uTreeNode);
                        }
                        else
                        {
                            if (obj.CtGUID != dataTypesGuid && obj.CtGUID != usersGuid)
                            {
                                uTreeNode = GenarateTree(uTreeNode);
                            }
                            else
                            {
                                uTreeNode = GenarateTree(uTreeNode, true);
                            }
                            ownerUltraTreeNode.Nodes.Add(uTreeNode);
                        }
                        ownerUltraTreeNode.Override.NodeStyle = Infragistics.Win.UltraWinTree.NodeStyle.Standard;
                    }
                }
            }
            else
            {
                ISingleResult<GetTreeResult> gtreeres = mShellDataContext.GetTree((Guid?)((TagInfo)(mActiveParentNode.Tag)).CtGUID);
                treeResults = gtreeres.Cast<INodeObject>().ToList<INodeObject>();

                UltraTreeNode uTNode = new UltraTreeNode(treeResults[0].Name);
                uTNode.Tag = treeResults[0].ChildGUID;
                ownerUltraTreeNode = this.trChildData.Nodes[this.trChildData.Nodes.Add(uTNode)];
                ownerUltraTreeNode.Override.NodeStyle = Infragistics.Win.UltraWinTree.NodeStyle.Standard;
                uTNode.Expanded = true;
            }

            foreach (INodeObject node in GetNextNode(tree, treeResults))
            {
                AddNode(node, ownerUltraTreeNode);
            }
        }

        private IEnumerable<INodeObject> GetNextNode(INodeObject tree, IEnumerable<INodeObject> treeResults)
        {
            if (treeResults == null)
                return new List<INodeObject>();
            IEnumerable<INodeObject> qq;
            if (tree != null)
            {
                qq = from g in treeResults
                     where (((INodeObject)(g)).ParentGUID == tree.ChildGUID)
                     select g;
            }
            else
            {
                qq = from g in treeResults
                     where (((INodeObject)(g)).ParentGUID == ((TagInfo)(mActiveParentNode.Tag)).CtGUID)
                     select g;
            }
            return qq;
        }

        private void ubExit_Click(object sender, System.EventArgs e)
        {
            this.Close();
        }

        private void btnSearch_Click(object sender, EventArgs e)
        {
            int StartIndex = 0;

            if (this.trParentData.SelectedNodes.Count > 0 && this.trParentData.SelectedNodes[0].Parent.Index == 1)
                StartIndex = this.trParentData.SelectedNodes[0].Index + 1;

            for (int i = StartIndex; i < this.trParentData.Nodes[1].Nodes.Count; i++)
            {
                if (this.trParentData.Nodes[1].Nodes[i].ToString().Contains(this.txtSearch.Text.ToString()))
                {
                    this.trParentData.Nodes[1].Nodes[i].Selected = true;
                    break;
                }
            }

        }

        private void txtSearch_TextChanged(object sender, EventArgs e)
        {
            if (this.trParentData.SelectedNodes.Count > 0)
            {
                this.trParentData.SelectedNodes[0].Selected = false;
            }
        }

        private void txtSearch_Enter(object sender, EventArgs e)
        {
            InputLanguage.CurrentInputLanguage = InputLanguage.FromCulture(new CultureInfo("ka-ge"));
        }
    }
    public class TagInfo
    {
        private Guid cGUID;
        public Guid CGUID
        {
            get { return cGUID; }
            set { cGUID = value; }
        }

        private Guid ctGUID;
        public Guid CtGUID
        {
            get { return ctGUID; }
            set { ctGUID = value; }
        }

        private Guid pGUID;
        public Guid PGUID
        {
            get { return pGUID; }
            set { pGUID = value; }
        }

        private Guid ptGUID;
        public Guid PtGUID
        {
            get { return ptGUID; }
            set { ptGUID = value; }
        }

        public TagInfo(Guid cG, Guid ctG)
        {
            cGUID = cG;
            ctGUID = ctG;
        }
        public TagInfo(Guid cG, Guid ctG, Guid pG, Guid ptG)
        {
            cGUID = cG;
            ctGUID = ctG;
            pGUID = pG;
            ptGUID = ptG;
        }
    }
}

